package service

import (
	"context"
	"database/sql"
	"github.com/pkg/errors"
	"gorm.io/gorm"
	"prod/api/prod"
	"prod/internal/constant"
	"prod/internal/model"
	"prod/pkg/util"
)

func (s *Service) GetPropertyGroupList(ctx context.Context, req *prod.GetPropertyGroupRequest) (
	resp *prod.GetPropertyGroupResponse, err error) {
	if err = s.dao.CheckPermission(ctx, req.Token, req.PStoreId); err != nil {
		return
	}
	var groups []*model.Group
	if groups, err = s.dao.LoadGroupList(ctx, req.Token.SgId, req.PStoreId, req.Nature); err != nil {
		return
	}
	groupIdMap := make(util.Int32BoolMap)
	for _, group := range groups {
		groupIdMap[group.ID] = true
	}
	resp = &prod.GetPropertyGroupResponse{Groups: make([]*prod.GroupView, len(groups))}
	for i, group := range groups {
		resp.Groups[i] = &prod.GroupView{
			Name:  group.Name,
			Items: group.Items,
		}
	}
	return
}

func (s *Service) CreatePropertyGroup(ctx context.Context, req *prod.CreatePropertyGroupRequest) (
	resp *prod.DefaultResp, err error) {
	if err = s.dao.CheckPermission(ctx, req.Token, req.PStoreId); err != nil {
		return
	}
	if err = s.dao.Transaction(ctx, func(ctx context.Context) (err error) {
		if _, err = s.dao.GetGroupByName(
			ctx, req.Name, req.Token.SgId, req.PStoreId); err == nil {
			err = constant.ErrDuplicateInput
			return
		} else if errors.Cause(err) != gorm.ErrRecordNotFound {
			return
		} else {
			group := &model.Group{
				Name:     req.Name,
				SgId:     req.Token.SgId,
				PStoreId: req.PStoreId,
				Nature:   uint8(req.Nature),
				Items:    req.Items,
				Operator: req.Token.EmpId,
			}
			if err = s.dao.Create(ctx, group); err != nil {
				return
			}
		}
		return
	}); err != nil {
		return
	}
	resp = &prod.DefaultResp{Status: true}
	return
}

func (s *Service) EditPropertyGroup(ctx context.Context, req *prod.EditPropertyGroupRequest) (
	resp *prod.DefaultResp, err error) {
	if err = s.dao.CheckPermission(ctx, req.Token, req.PStoreId); err != nil {
		return
	}
	if err = s.dao.Transaction(ctx, func(ctx context.Context) (err error) {
		// 锁定正确状态的记录
		group := &model.Group{}
		if err = s.dao.LockObjectByName(ctx, group, req.Name, req.Token.SgId, req.PStoreId); err != nil {
			if errors.Cause(err) == gorm.ErrRecordNotFound {
				err = constant.ErrObjectNotExist
			}
			return
		}
		// 删除旧关联
		group.Items = req.Items
		group.Operator = req.Token.EmpId
		if err = s.dao.Save(ctx, group); err != nil {
			return
		}
		return
	}); err != nil {
		return
	}
	resp = &prod.DefaultResp{Status: true}
	return
}

func (s *Service) DeletePropertyGroup(ctx context.Context, req *prod.DeletePropertyGroupRequest) (
	resp *prod.DefaultResp, err error) {
	if err = s.dao.CheckPermission(ctx, req.Token, req.PStoreId); err != nil {
		return
	}
	if err = s.dao.Transaction(ctx, func(ctx context.Context) (err error) {
		// 锁定正确状态的记录
		group := &model.Group{}
		if err = s.dao.LockObjectByName(ctx, group, req.Name, req.Token.SgId, req.PStoreId); err != nil {
			if errors.Cause(err) == gorm.ErrRecordNotFound {
				err = constant.ErrObjectNotExist
			}
			return
		}
		group.Status = sql.NullBool{}
		group.Operator = req.Token.EmpId
		if err = s.dao.Save(ctx, group); err != nil {
			return
		}
		return
	}); err != nil {
		return
	}
	resp = &prod.DefaultResp{Status: true}
	return
}
